// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Kismet/BlueprintFunctionLibrary.h"
#include "UObject/SoftObjectPtr.h"

#include "LyraSystemStatics.generated.h"

template <typename T> class TSubclassOf;

class AActor;
class UActorComponent;
class UObject;
struct FFrame;

/**
 * Lyra 系统静态函数库
 */
UCLASS()
class ULyraSystemStatics : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	/**
	 * 从主资产 ID 获取类型化的软对象引用，即使资产未加载也能工作
	 * @param PrimaryAssetId 主资产 ID
	 * @param ExpectedAssetType 期望的资产类型
	 * @return 类型化的软对象引用
	 */
	UFUNCTION(BlueprintPure, Category = "AssetManager", meta=(DeterminesOutputType=ExpectedAssetType))
	static TSoftObjectPtr<UObject> GetTypedSoftObjectReferenceFromPrimaryAssetId(FPrimaryAssetId PrimaryAssetId, TSubclassOf<UObject> ExpectedAssetType);

	/**
	 * 从用户可见体验名称获取主资产 ID
	 * @param AdvertisedExperienceID 用户可见体验 ID
	 * @return 主资产 ID
	 */
	UFUNCTION(BlueprintCallable)
	static FPrimaryAssetId GetPrimaryAssetIdFromUserFacingExperienceName(const FString& AdvertisedExperienceID);

	/**
	 * 开始下一局游戏（仅限服务器端调用）
	 * @param WorldContextObject 世界上下文对象
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Lyra", meta = (WorldContext = "WorldContextObject"))
	static void PlayNextGame(const UObject* WorldContextObject);

	/**
	 * 在目标角色上的所有网格组件的所有部分上设置标量参数值
	 * @param TargetActor 目标角色
	 * @param ParameterName 参数名称
	 * @param ParameterValue 参数值
	 * @param bIncludeChildActors 是否包含子角色
	 */
	UFUNCTION(BlueprintCallable, Category = "Rendering|Material", meta=(DefaultToSelf="TargetActor"))
	static void SetScalarParameterValueOnAllMeshComponents(AActor* TargetActor, const FName ParameterName, const float ParameterValue, bool bIncludeChildActors = true);

	/**
	 * 在目标角色上的所有网格组件的所有部分上设置向量参数值
	 * @param TargetActor 目标角色
	 * @param ParameterName 参数名称
	 * @param ParameterValue 参数值
	 * @param bIncludeChildActors 是否包含子角色
	 */
	UFUNCTION(BlueprintCallable, Category = "Rendering|Material", meta=(DefaultToSelf="TargetActor"))
	static void SetVectorParameterValueOnAllMeshComponents(AActor* TargetActor, const FName ParameterName, const FVector ParameterValue, bool bIncludeChildActors = true);

	/**
	 * 在目标角色上的所有网格组件的所有部分上设置颜色参数值
	 * @param TargetActor 目标角色
	 * @param ParameterName 参数名称
	 * @param ParameterValue 参数值
	 * @param bIncludeChildActors 是否包含子角色
	 */
	UFUNCTION(BlueprintCallable, Category = "Rendering|Material", meta=(DefaultToSelf="TargetActor"))
	static void SetColorParameterValueOnAllMeshComponents(AActor* TargetActor, const FName ParameterName, const FLinearColor ParameterValue, bool bIncludeChildActors = true);

	/**
	 * 查找继承自给定类的所有组件
	 * @param TargetActor 目标角色
	 * @param ComponentClass 组件类
	 * @param bIncludeChildActors 是否包含子角色
	 * @return 组件数组
	 */
	UFUNCTION(BlueprintCallable, Category = "Actor", meta=(DefaultToSelf="TargetActor", ComponentClass="/Script/Engine.ActorComponent", DeterminesOutputType="ComponentClass"))
	static TArray<UActorComponent*> FindComponentsByClass(AActor* TargetActor, TSubclassOf<UActorComponent> ComponentClass, bool bIncludeChildActors = true);
};